<?php

/**
 * Main template parsing class
 * 
 * @package template
 * @author Jacob Wright
 */

class TemplateParser {
	
	/**
	 * Makes sure the template is parsed, cached, and up to date
	 * 
	 * @param string $template The path to the template file to be processed
	 * @return boolean Whether or not the template was updated. true = updated, false = current
	 */
	function update($template, $phpfile) {
		if (!is_file($template)) trigger_error("Error: Template file \"$template\" does not exist", E_USER_WARNING);
		
		if (!file_exists($phpfile) || filemtime($template) > filemtime($phpfile)) {
			TemplateParser::parseTemplate($template, $phpfile);
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * Parses a template file into it's equivalent PHP version
	 * 
	 * @param string $template Path of the template to be cached
	 * @param string $cachefile Path of the PHP file that will be created
	 */
	function parseTemplate($template, $phpfile) {
		global $BLUEPRINT_COMPONENTS_DIRS;
		static $files;
		if (!$files) {
			$files = array();
			foreach ($BLUEPRINT_COMPONENTS_DIRS as $path) {
				$dir = dir($path);
				while (($file = $dir->read()) !== false) {
					$fullPath = $path . DIRECTORY_SEPARATOR . $file;
					if (is_file($fullPath)) {
						$component = str_replace('.php', '', $file);
						$lcComponent = strtolower($component);
						if (!isset($files[$lcComponent]))
							$files[$lcComponent] = array("name" => $component . 'Component', "path" => $fullPath);
					}
				}
			}
		}
		
		include_once(BLUEPRINT_DIR . '/parsing/HTMLDocument.php');
		include_once(BLUEPRINT_DIR . "/components/BlueprintComponent.php");
		$doc = new HTMLDocument($template);
		
		for ($i = 0; $i < count($doc->allNodes); $i++) {
			$element = $doc->allNodes[$i];
			// add components to an array, then process after they are removed from element so that
			// their attributes don't interfere in each other's processing
			$components = array();
			foreach ($element->attributes as $attrib => $value) {
				if ($attrib[0] == "_") {
					$component = $files[strtolower(substr($attrib, 1))];
					if (!isset($component)) {
						trigger_error("No Blueprint components match $attrib in template $template on line <strong>$element->startLine</strong>", E_USER_WARNING);
						break;
					}
					include_once($component["path"]);
					unset($element->attributes[$attrib]);
					$className = $component["name"];
					$components[$className] = $value;
				}
			}
			foreach ($components as $comp => $value) {
				new $comp($element, $value);
			}
		}
		
		mkdir_r(dirname($phpfile));
		$fp = fopen($phpfile, 'w');
		fwrite($fp, $doc->toString());
		fclose($fp);
	}
}
?>
